/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "M051Series.h"
#include "Driver\DrvGPIO.h"

#include "FreeRTOS_Test.h"
#include "FreeRTOS.h"
#include "task.h"

#define GPIOStack_Size	configMINIMAL_STACK_SIZE

void vGPIOTask(void *pvParameters);

void P0P1Callback(uint32_t u32P0Status, uint32_t u32P1Status)
{
    printf("P0P1 Interrupt! P0:0x%04x  P1:0x%04x\n", u32P0Status, u32P1Status);

    /* Toggle LED */
    P20_DOUT = P20_DOUT ^ 1;
}

void P2P3P4Callback(uint32_t u32P2Status, uint32_t u32P3Status, uint32_t u32P4Status)
{ 
    /* Toggle LED */
    P20_DOUT = P20_DOUT ^ 1;

    printf("P2P3P4 Interrupt! P2:0x%04x  P3:0x%04x  P4:0x%04x\n", u32P2Status, u32P3Status, u32P4Status);
}

void EINT0Callback(void)
{    
    /* Toggle LED */
    P20_DOUT = P20_DOUT ^ 1;

    printf("EINT0 Interrupt!\n");
}

void EINT1Callback(void)
{    
    /* Toggle LED */
    P20_DOUT = P20_DOUT ^ 1;

    printf("EINT1 Interrupt!\n");
}

void Delay(uint32_t ucnt)
{
    volatile uint32_t i = ucnt;

    while (i--);
}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/    
#if 0
int main (void)
#else
void vGPIOTask(void *pvParameters)
{
	//STR_UART_T param;
    int32_t i32Err;
#if 0
	UNLOCKREG();
    SYSCLK->PWRCON.XTL12M_EN = 1;
    /* Waiting for 12M Xtal stalble */
    Delay(0x100000);

	/* Select UART Clock Source From 12Mhz*/
	DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0); 

	DrvGPIO_InitFunction(E_FUNC_UART0);
	
    param.u32BaudRate        = 115200;
    param.u8cDataBits        = DRVUART_DATABITS_8;
    param.u8cStopBits        = DRVUART_STOPBITS_1;
    param.u8cParity          = DRVUART_PARITY_NONE;
    param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;
    param.u8TimeOut        	 = 0;
    DrvUART_Open(UART_PORT0, &param);
#endif   
	printf("\n\n");
    printf("+-------------------------------------------------------------------+\n");
    printf("|                      GPIO Driver Sample Code                      |\n");
    printf("+-------------------------------------------------------------------+\n");

    /*-----------------------------------------------------------------------------------------------------*/
    /* Basic Setting                                                                                       */
    /*-----------------------------------------------------------------------------------------------------*/    
    /*-----------------------------------------------------------------------------------------------------*/
    /* Configure Bit0 in Port1 to Output pin and Bit1 in Port4 to Input pin then close it                  */
    /*-----------------------------------------------------------------------------------------------------*/
	printf("  >> Please connect P25 and P41 first <<\n");
	
	DrvGPIO_Open(E_PORT2, E_PIN5, E_IO_OUTPUT);
	DrvGPIO_Open(E_PORT4, E_PIN1, E_IO_INPUT);
	
    i32Err = 0;
    printf("  GPIO Input/Output test ................................ ");

    DrvGPIO_ClrBit(E_PORT2, E_PIN5);
	if (DrvGPIO_GetBit(E_PORT4, E_PIN1) != 0)
	{
		i32Err = 1;
	}

    DrvGPIO_SetBit(E_PORT2, E_PIN5);	
	if (DrvGPIO_GetBit(E_PORT4, E_PIN1) != 1)
	{
		i32Err = 1;
	}

    if ( i32Err )
    { 
	    printf("[FAIL]\n");
        printf("\n  (Please make sure P10 and P41 are connected)\n");
    }
    else
    {
        printf("[OK]\n");
    }
    
    DrvGPIO_Close(E_PORT2, E_PIN5);
	DrvGPIO_Close(E_PORT4, E_PIN1);
 
    /*-----------------------------------------------------------------------------------------------------*/
    /* GPIO Interrupt Test                                                                                 */
    /*-----------------------------------------------------------------------------------------------------*/    
    
    printf("\n  P13, P45, P32(INT0) and P33(INT1) are used to test interrupt\n  and control LEDs(P20)\n");    

    /* Configure P20 for LED control */
    DrvGPIO_Open(E_PORT2, E_PIN0, E_IO_OUTPUT);

    /* Configure P13 as general GPIO interrupt */
    DrvGPIO_Open(E_PORT1, E_PIN3, E_IO_INPUT);

    /* The Quasi-bidirection mode could be used as input with pull up enable */
    DrvGPIO_Open(E_PORT4, E_PIN5, E_IO_QUASI);

    /* Configure general interrupt callback function for P0/P1 and P2/P3/P4 */
    DrvGPIO_SetIntCallback(P0P1Callback, P2P3P4Callback);

    DrvGPIO_EnableInt(E_PORT1, E_PIN3, E_IO_RISING, E_MODE_EDGE);

    /* IO_FALLING means low level trigger if it is in level trigger mode */
    DrvGPIO_EnableInt(E_PORT4, E_PIN5, E_IO_FALLING, E_MODE_LEVEL); 

    DrvGPIO_SetDebounceTime(6, E_DBCLKSRC_HCLK);    
    DrvGPIO_EnableDebounce(E_PORT1, E_PIN3);
    DrvGPIO_EnableDebounce(E_PORT4, E_PIN5);

    DrvGPIO_EnableDebounce(E_PORT3, E_PIN2);
    DrvGPIO_EnableDebounce(E_PORT3, E_PIN3);

    /* Configure external interrupt */
    DrvGPIO_EnableEINT(E_EINT0_PIN, E_IO_FALLING, E_MODE_EDGE, EINT0Callback);
    DrvGPIO_EnableEINT(E_EINT1_PIN, E_IO_BOTH_EDGE, E_MODE_EDGE, EINT1Callback);

    /* Waiting for interrupts */
    for(;;);
}
#endif

void vStartGPIOTasks( unsigned portBASE_TYPE uxPriority )
{
	xTaskCreate( vGPIOTask, ( signed char * ) "GPIO", GPIOStack_Size, NULL, uxPriority, ( xTaskHandle * ) NULL );
}
